const path = require("path");
const webpack = require("webpack");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");

class MyPlugin {
  //清除打包完成的js文件中没必要的注释
  apply(compiler) {
    //apply在webpack启动时自动调用，compiler参数是webpack工作过程最核心的对象，包含了此次构建的所有配置信息，也是通过这个对象注册所有钩子函数
    compiler.hooks.emit.tap("MyPlugin", (compilation) => {
      //emit钩子将在webpack即将往输出目录输出文件时执行，tap注册钩子函数，参数1：插件名，参数2：需要挂在的函数
      //compilation可以理解为此次打包的上下文，打包结果都在compilation对象中
      for (const name in compilation.assets) {
        //console.log(name); //文件名
        //console.log(compilation.assets[name].source()); //内容
        if (name.endsWith(".js")) {
          const contents = compilation.assets[name].source();
          const withoutComments = contents.replace(/\/\*\*+\*\//g, "");
          compilation.assets[name] = {
            source: () => withoutComments,
            size: () => withoutComments.length, //内部要求必须方法
          };
        }
      }
    });
  }
}

module.exports = {
  mode: "none",
  entry: "./src/main.js", //入口文件，相对路径./必须加
  output: {
    filename: "bundle.js", //指定输出文件名
    path: path.join(__dirname, "dist"), //指定输出文件所在目录，必须是绝对路径
    //publicPath: "dist/", // 网站资源文件目录，默认''根目录
  },
  devtool: "source-map", // 配置开发过程中的辅助工具
  devServer: {
    contentBase: "./public", //指定额外的静态资源路径可以是字符串和数组
    hot: true,
    proxy: {
      //添加代理服务配置，每一个属性都是一个代理规则配置，属性名就是需要被代理的请求路径名前缀，值为前缀所匹配到的代理规则配置
      "/api": {
        //请求http://localhost:8080/api/users=https://api.github.com/api/users
        target: "https://api.github.com",
        pathRewrite: {
          //代理路径中的/api需要重写去掉
          "^/api": "", //正则匹配
        },
        //不能使用localhost:8080作为请求github的主机名
        //请求github服务器时会带一个主机名，默认是浏览器发起请求的主机名（localhost:8080），服务器需要根据主机名判断请求是属于哪个网站，从而把请求响应指派到该网站，对于localhost github服务器不认识，所以需要修改
        changeOrigin: true, //默认服务器会以我们实际在浏览器中请求的主机名作为代理请求的主机名，true会以代理请求发生过程的主机名（api.github.com/api）去请求
      },
    },
  },
  module: {
    rules: [
      {
        test: /.js$/, //指定js加载器为babel，取代默认加载器
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
          },
        },
      },
      {
        test: /.css$/,
        use: ["style-loader", "css-loader"], //从右往左执行
      },
      {
        test: /.jpg$/,
        use: {
          loader: "url-loader",
          options: {
            limit: 10 * 1024, //10kb，10kb以下的文件转成dataurl
          },
        },
      },
      // {
      //   test: /.html$/,
      //   use: {
      //     loader: "html-loader",
      //     options: {},
      //   },
      // },
    ],
  },
  plugins: [
    new CleanWebpackPlugin(),
    //生成index.html
    new HtmlWebpackPlugin({
      title: "webpack plugin sample",
      meta: {
        viewport: "width=device-width",
      },
      template: "./src/index.html",
    }),
    //生成about.html
    new HtmlWebpackPlugin({
      filename: "about.html",
      template: "./src/index.html",
    }),
    一般在项目的上线前使用，开发过程不使用，打包频繁重复执行，文件较大时，打包开销就大
    new CopyWebpackPlugin({
      patterns: [{ from: path.join(__dirname, "public"), to: "public" }],
    }),
    new MyPlugin(),
    new webpack.HotModuleReplacementPlugin(),
  ],
  optimization: {
    //集中提供webpack优化配置
    concatenateModules: true, //合并模块
    usedExports: true, //打包文件中只导出使用了的成员
    // minimize: true, //压缩没有用到的代码
  },
};
